// FILE: Chip8Emulator.h by Richard Hughes 27/04/2012
//
// DESC: Defines the chip 8 emulator class

#ifndef __chip8emulator_h__
#define __chip8emulator_h__

// INCLUDES
#include "IEmulator.h"
#include "Chip8RAM.h"
#include "Chip8ROM.h"
#include "Chip8CPU.h"
#include "Chip8Screen.h"
#include "Chip8Keyboard.h"
#include "Chip8Buzzer.h"
#include "Chip8Disassembler.h"
#include "Chip8Debugger.h"

namespace Emulator
{
namespace Chip8
{

// ENUMS
enum EmulatorRunningMode
{
	EmulatorRunningMode_Chip8,
	EmulatorRunningMode_SuperChip8,
	EmulatorRunningMode_MegaChip8,
}; // end EmulatorRunningMode

/*************************************************************/
//
// CLASS: Chip8Emulator
//
// DESC: The Chip 8 Emulator definition
//
/*************************************************************/

class Chip8Emulator : IEmulator
{
	Chip8RAM _ram;
	Chip8ROM _rom;
	Chip8CPU _cpu;
	Chip8Screen* _display;
	Chip8Keyboard* _keyboard;
	Chip8Buzzer* _buzzer;
	Chip8Debugger _debugger;

	// debug stuff
	string _executedCode;
	Chip8Disassembler _disassembler;

	bool _running;

	EmulatorRunningMode _runningMode;
public:

	Chip8Emulator();
	~Chip8Emulator();

	// inits this emulator
	bool Init();

	// runs once per frame
	bool Frame();

	// shutsdown this emulator
	bool Shutdown();

	// loads the ROM
	bool LoadROM(string fileName);

	inline Chip8Screen* const GetDisplay() { return this->_display; }
	inline void SetDisplay(Chip8Screen* display) { this->_display = display; }

	inline Chip8Keyboard* const GetKeyboard() { return this->_keyboard; }
	inline void SetKeyboard(Chip8Keyboard* keyboard) { this->_keyboard = keyboard; }

	inline Chip8Buzzer* const GetBuzzer() { return this->_buzzer; }
	inline void SetBuzzer(Chip8Buzzer* buzzer) { this->_buzzer = buzzer; }

	inline Chip8ROM* const GetROM() { return &this->_rom; }
	inline Chip8Debugger* const GetDebugger() { return &this->_debugger; }
	inline Chip8CPU* const GetCPU() { return &this->_cpu; }
	inline Chip8Disassembler* const GetDisassembler() { return &this->_disassembler; }
	inline Chip8RAM* const GetRAM() { return &this->_ram; }

	void Exit()
	{
		this->_running = false;
	}

	void EnterChip8Mode();
	void EnterSuperChip8Mode();
	void EnterMegaChip8Mode();

	EmulatorRunningMode GetRunningMode()
	{
		return this->_runningMode;
	}

}; // Chip8Emulator

} // end namespace Chip8
} // end namespace Emulator

#endif // __chip8emulator_h__

// EOF: Chip8Emulator.h